const EventEmitter = require("events");
const fs = require("fs");
const qs = require("qs");
const axios = require("axios");
const path = require("path");

const INFO = console.log;
const ERROR = console.error;
const instance = axios.create({
    timeout: 20000,
});
const DownloadManager = new EventEmitter();
const DataManager = require("./DataManager");
const RESOURCE_PATH = path.join(__dirname, "../../data/img/");
const URLS = [
    {
        url: "api/terminal/program/getEmployeePublish",
        key: "product",
    },
];
/**
 * @description: 请求
 * @param {string} 服务地址
 * @param {number} 设备id
 * @return {*}
 */
const requestData = (SERVER_HOST, agentDeviceId) => {
    let url = SERVER_HOST + DownloadManager.urls[0].url;
    let key = DownloadManager.urls[0].key;
    instance
        .get(
            url + "?" +
            qs.stringify({
                agentDeviceId,
            })
        )
        .then(async (result) => {
            INFO.info(`start download url : ${result.config.url}`);
            let {
                code,
                data,
                msg,
            } = result.data;
            if (code !== 0) return ERROR.error("requset no data:" + msg);
            DownloadManager.total = data.length;
            INFO.info(`start handleData:total:${data.length}`);
            if (data.length) {
                let _data = await handleData(data);
                DataManager.saveData(_data, key);
            }
            INFO.info(`end handleData`);
            DownloadManager.progress = 0;
            DownloadManager.urls.shift();
            if (DownloadManager.urls.length)
                return requestData(SERVER_HOST, agentDeviceId);
            DownloadManager.emit("update");
        })
        .catch((err) => {
            if (DownloadManager.urls.length)
                setTimeout(
                    () => requestData(SERVER_HOST, agentDeviceId),
                    20000
                );

            ERROR.error("requset error:" + err);
        });
};
/**
 * @description: 处理数据
 * @param {Array} 数据集合
 * @return {*}
 */
const handleData = (dataObj) => {
    let Data = [];
    return new Promise((reslove) => {
        let thread = async () => {
            DownloadManager.progress++;
            const data = dataObj.shift();
            const { avatar, certificateList, id } = data;
            let imageData = [];

            //分析需要下载的图片(不需要考虑缩略图，因为将来及时是头像也会采用大图)
            if (avatar) {
                imageData.push({ key: "avatar", url:avatar });
            }
            if (certificateList) {
                certificateList.forEach(certificate=>imageData.push({ key: "certificateList", url: certificate })) ;
            }
            
            let result = []; //定义一个用于存储下载图片结果的数组
            if (imageData.length) {
                result = await downloadImage(Object.assign([], imageData));
            }
            //console.log(`download success ${result.length}`);
            DownloadManager.emit(
                "progress",
                parseFloat(
                    DownloadManager.progress / DownloadManager.total
                ).toFixed(2) * 100
            );

            //将下载到的图片地址替换之前原始数据中的相应地址
            let _result = {certificateList:[]}; //先声明一个临时对象
            result.forEach((arr) =>{
                //如果 key 为 certificateList 则对应的是 原始数据中的 certificateList
                if(arr.key==='certificateList'){
                _result.certificateList.push(arr.url)
                return 
                }
                //如果 key 不为 certificateList，那么肯定对应的是 原始数据中的 avatar
                _result[arr.key] = arr.url
            });
            Data.push({ ...data, ..._result }); //最终合并(整合)数据
            if (dataObj.length) return thread();
            reslove(Data);
        };
        thread();
    });
};

/**
 * @description: 下载图片
 * @param {Array} 图片地址
 * @return {*}
 */
const downloadImage = (imageData) => {
    let errorCount = 0;
    return new Promise((reslove) => {
        let result = [];
        let thread = () => {
            if (!imageData.length) return reslove(result);
            const _imageObj = imageData[0];
            const filename = decodeURIComponent(
                path.basename(_imageObj.url).split("?")[0]
            );
            const _file = path.join(RESOURCE_PATH, filename);
            if (fs.existsSync(_file)) {
                result.push({ ..._imageObj, url: filename });
                imageData.shift();
                return thread();
            }
            let retry = (e) => {
                errorCount += 1;
                //console.log(`download image error ${errorCount} ${e} `);
                setTimeout(() => {
                    if (errorCount >= 5) {
                        try {
                            fs.unlinkSync(_file);
                        } catch { }
                        errorCount = 0;
                        imageData.shift();
                    }
                    thread();
                }, 2000);
            };
            // console.log(_imageObj.url);
            instance
                .get(_imageObj.url, { responseType: "stream" })
                .then((res) => {
                    const ws = fs.createWriteStream(_file);
                    res.data.pipe(ws);
                    ws.on("close", () => {
                        if (res.headers["content-length"] !== ws.bytesWritten) {
                            return retry();
                        }
                        result.push({ ..._imageObj, url: filename });
                        imageData.shift();
                        thread();
                    });
                })
                .catch(retry);
        };
        thread();
    });
};
/**
 * @description: 入口
 * @param {string} 设备id
 * @param {string} 服务ip
 * @return {*}
 */
DownloadManager.start = (id, serverip) => {
    DownloadManager.urls = Object.assign([], URLS);
    DownloadManager.progress = 0;
    DownloadManager.errorData = [];
    return requestData(serverip, id);
};

module.exports = DownloadManager;
